package tr.richfacesext.components.rating;

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import tr.richfacesext.components.ComponentConstants;

/**
 * 
 * @author mert
 *
 */
public class RatingRenderer extends Renderer {

	private Logger log = LoggerFactory.getLogger(RatingRenderer.class);

	@Override
	public void decode(FacesContext context, UIComponent component) {
		Rating rating = (Rating) component;
		String submittedVal = context.getExternalContext()
				.getRequestParameterMap().get(
						getClientId(rating, context) + "_hiddenVal");
		log.debug("Submitted value: {}", submittedVal);
		Float floatVal;
		if (submittedVal == null) {
			floatVal = new Float(0.0);
		} else {
			floatVal = new Float(submittedVal);
		}
		rating.setValue(floatVal);
		rating.setValid(true);
	}

	public void encodeEnd(FacesContext context, UIComponent component)
			throws IOException {
		ResponseWriter writer = context.getResponseWriter();
		Rating rating = (Rating) component;

		if (!rating.isFixedValue()) {
			encodeIncludeScript(context, writer, rating);
		}
		encodeWidget(context, writer, rating);
	}

	private void encodeIncludeScript(FacesContext context,
			ResponseWriter writer, Rating rating) throws IOException {
		writer.startElement("script", rating);
		writer.writeAttribute("type", "text/javascript", null);
		String contextPath = context.getExternalContext()
				.getRequestContextPath()
				+ "/";
		writer.writeAttribute("src", contextPath
				+ RatingConstants.CORESCRIPT_VIEW_ID, null);
		writer.endElement("script");
		writer.write("\n");
	}

	private String getRatingValue(Rating rating) {
		return rating.getRatingValue() == null ? "0.0" : rating
				.getRatingValue().toString();
	}

	private void encodeWidget(FacesContext context, ResponseWriter writer,
			Rating rating) throws IOException {
		String value = getRatingValue(rating);
		
		writer.write("<input id=\"" + getClientId(rating, context)
				+ "_hiddenVal\" name=\"" + getClientId(rating, context)
				+ "_hiddenVal\" type=\"hidden\" value=\"" + value
				+ "\"></input>");
		writer.write("\n");

		writer.startElement("img", rating);
		writer.writeAttribute("id", getClientId(rating, context), null);
		String contextPath = context.getExternalContext()
				.getRequestContextPath();
		Float ratingValue = rating.getRatingValue();
		if (ratingValue == null)
			ratingValue = new Float(0.0);

		String imgName = (new java.text.DecimalFormat("0.0"))
				.format(ratingValue);

		if (Integer.parseInt(imgName.substring(2)) > 4) {
			imgName = imgName.replace(imgName.substring(1), ".5");
		} else {
			imgName = imgName.replace(imgName.substring(1), ".0");
		}

		writer.writeAttribute("src", contextPath + ComponentConstants.FACES_PREFIX
				+ ComponentConstants.RICHFACESEXT_RESOURCE_LOADER_VIEW_ID + "/rating/"
				+ imgName + ".gif", null);
		if (!rating.isFixedValue()) {
			writer.writeAttribute("onmouseover",
					"this.style.cursor = CSS_POINTER;", null);
			writer.writeAttribute("onmousemove", "paintRating('"
					+ getClientId(rating, context) + "', '" + contextPath
					+ "', rateIt('" + getClientId(rating, context)
					+ "', event))", null);
			writer.writeAttribute("onmouseout", "finishRating('"
					+ getClientId(rating, context) + "', '" + contextPath
					+ "')", null);
			StringBuffer onclick = new StringBuffer();
			onclick.append("saveRating('" + getClientId(rating, context)
					+ "');");
			if (StringUtils.isNotEmpty(rating.getOnSuccessJSCall()))
				onclick.append(" " + rating.getOnSuccessJSCall());
			writer.writeAttribute("onclick", onclick, null);
		}
		writer.endElement("img");
		writer.write("\n");
	}

	private String getClientId(Rating rating, FacesContext context) {
		return rating.getClientId(context).replace(":", "_");
	}
}